今天的題目功能是當我們按下checkbox以後,按著shift不放,再按下另一個checkbox,會把兩個checkbox之間的checked都設為true,主要重點為邏輯判斷。
如下圖:
首先,我們先獲取所有type為check的input並利用Array.from轉成陣列。
並設置firstCheck來儲存第一個按下的下標。
const checkBox = Array.from(document.querySelectorAll('.item input[type="checkbox"]'));
let firstCheck = null;
而後我們在賦予每個checkbox click事件。
checkBox.forEach(item => {
item.addEventListener('click', clickHandler);
});
再來我們寫一下按下checkbox的處理:
首先在event下有一個為shiftKey的屬性,可以判斷是否按著shift
接著,我們在判斷是否當前按下的input為checked,沒有的話就將第一個按下的firstCheck設為null,有的話就在進行一次判斷,判斷是否有按下shift不放,且我們第一個按下的firstCheck為true,沒有的話,就利用indexOf方法
(會回傳元素於陣列中第一個被找到之index)將當前所按下input下標給儲存至firstCheck,有的話我們就去設置一個變數nowCheck去獲取當前下標。
再來就是對所有checkbox利用slice方法(回傳一個新陣列物件,為原陣列選擇之 begin 至 end(不含 end)參數為(begin,end))
將兩個input之間的所有input的checked都改為true,因為我們可能由下案到上,故firstCheck不一定小於nowCheck
,故利用Math.max,min去抓最大值(放後面)及最小值(放前面)
,最後再利用forEach對每個處理好的input的checked改為true即可。
function clickHandler(e) {
// console.log(e.shiftKey); // 當按著shift去check就會為true
if (this.checked) {
// 當按著shift且當前有按下check
if (e.shiftKey && firstCheck !== null) {
// 獲取當前的下標
let nowCheck = checkBox.indexOf(this);
// 利用Math.max,min去抓最大值(放後面)及最小值(放前面)
checkBox.slice(Math.min(nowCheck, firstCheck), Math.max(nowCheck, firstCheck)).forEach(item => {
item.checked = true;
});
}
// 如果第一個按下的input為checked,就儲存其下標
firstCheck = checkBox.indexOf(this);
} else {
firstCheck = null;
}
}